package com.example.tellwin;

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.telecom.Call;
import android.util.Log;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat;

import com.apkfuns.logutils.LogUtils;
import com.example.tellwin.api.TwjfApi;
import com.example.tellwin.common.Common;
import com.example.tellwin.event.CallEvent;
import com.example.tellwin.event.IMEventBean;
import com.example.tellwin.event.OrderDetailEvent;
import com.example.tellwin.event.WebSocketEvent;
import com.example.tellwin.home.bean.HomeNumberBean;
import com.example.tellwin.model.TRTCCalling;
import com.example.tellwin.model.TRTCCallingDelegate;
import com.example.tellwin.model.impl.TRTCCallingImpl;
import com.example.tellwin.question.act.AnswerActivity;
import com.example.tellwin.test.GenerateTestUserSig;
import com.example.tellwin.tic.TICManager;
import com.example.tellwin.utils.CommonUtils;
import com.example.tellwin.utils.ServiceUtils;
import com.example.tellwin.utils.StatusBarUtil;
import com.example.tellwin.utils.ToastUtil;
import com.google.gson.Gson;
import com.tencent.imsdk.session.SessionWrapper;
import com.tencent.imsdk.v2.V2TIMCallback;
import com.tencent.imsdk.v2.V2TIMManager;
import com.tencent.imsdk.v2.V2TIMMessage;
import com.tencent.imsdk.v2.V2TIMSDKConfig;
import com.tencent.imsdk.v2.V2TIMSDKListener;
import com.tencent.imsdk.v2.V2TIMSimpleMsgListener;
import com.tencent.imsdk.v2.V2TIMUserInfo;
import com.tencent.imsdk.v2.V2TIMValueCallback;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;
import okio.ByteString;

import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static com.example.tellwin.model.TRTCCalling.TYPE_AUDIO_CALL;
import static com.example.tellwin.model.TRTCCalling.TYPE_VIDEO_CALL;

public class CallService extends Service {

    private static final int NOTIFICATION_ID = 1001;
    private TRTCCalling mTRTCCalling;
    protected TICManager mTicManager;
    WebSocket webSocket;

    private Handler uiHandler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what){
                case 10001:
                    String text = (String) msg.obj;
                    HomeNumberBean homeNumberBean = new Gson().fromJson(text ,HomeNumberBean.class);
                    EventBus.getDefault().post(homeNumberBean);
                    break;
            }
        }
    };

    private TRTCCallingDelegate delegate = new TRTCCallingDelegate() {
        @Override
        public void onError(int code, String msg) {
            LogUtils.e(code + "-" + msg);
            ToastUtil.show(CallService.this , "对方已挂断！");
            if(MainApplication.getCurActivity() instanceof AnswerActivity){
                MainApplication.getCurActivity().finish();
            }
        }

        @Override
        public void onInvited(String sponsor, List<String> userIdList, boolean isFromGroup, int callType) {
            LogUtils.d("onInvited");
            if (MainApplication.Identity.equals(Common.NORMAL)) {
                if(MainApplication.getCurActivity() instanceof AnswerActivity){
                    ToastUtil.show(CallService.this , "有新的来电!");
                    return;
                }
                Intent intent = new Intent(CallService.this, AnswerActivity.class);
                intent.putExtra(Common.TYPE, Common.CALL_REMINDER);
                intent.putExtra(Common.USER_ID, sponsor);
                intent.putExtra(Common.Call_Type, callType);
                intent.addFlags(FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
            } else {
                CallEvent callEvent = new CallEvent();
                callEvent.type = Common.onInvited;
                callEvent.callType = callType;
                EventBus.getDefault().post(callEvent);
            }

        }

        @Override
        public void onGroupCallInviteeListUpdate(List<String> userIdList) {
            LogUtils.d("onGroupCallInviteeListUpdate");

        }

        @Override
        public void onUserEnter(String userId) {////不管是你打给他，还是他打给你，只要点击了通话，双方都会走这个
            LogUtils.d("onUserEnter");
            LogUtils.e(userId);
            CallEvent callEvent = new CallEvent();
            callEvent.type = Common.UserEnter;
            EventBus.getDefault().post(callEvent);
        }

        @Override
        public void onUserLeave(String userId) {//对方挂断了
            LogUtils.d("onUserLeave");
            CallEvent callEvent = new CallEvent();
            callEvent.type = Common.UserLeave;
            EventBus.getDefault().post(callEvent);
        }

        @Override
        public void onReject(String userId) {//你打电话给他，他拒绝了
            LogUtils.d("onReject");
            CallEvent callEvent = new CallEvent();
            callEvent.type = Common.onReject;
            EventBus.getDefault().post(callEvent);
        }

        @Override
        public void onNoResp(String userId) {
            LogUtils.d("onNoResp");
            CallEvent callEvent = new CallEvent();
            callEvent.type = Common.onNoResp;
            EventBus.getDefault().post(callEvent);
        }

        @Override
        public void onLineBusy(String userId) {
            LogUtils.d("onLineBusy");
            ToastUtil.show(CallService.this , "对方处于通话中，稍后再拨打");
            CallEvent callEvent = new CallEvent();
            callEvent.type = Common.onLineBusy;
            EventBus.getDefault().post(callEvent);
        }

        @Override
        public void onCallingCancel() {//来电人取消来电了
            LogUtils.d("onCallingCancel");
            CallEvent callEvent = new CallEvent();
            callEvent.type = Common.onCallingCancel;
            EventBus.getDefault().post(callEvent);
        }

        @Override
        public void onCallingTimeout() {//超时没人接电话
            LogUtils.d("onCallingTimeout");
            CallEvent callEvent = new CallEvent();
            callEvent.type = Common.onCallingTimeout;
            EventBus.getDefault().post(callEvent);
        }

        @Override
        public void onCallEnd() {//通话中，打电话给你的人挂断了 ；你打电话个他，他拒绝了会走onReject在走onCallEnd
            LogUtils.d("onCallEnd");
          /*  CallEvent callEvent = new CallEvent();
            callEvent.type = Common.onCallEnd;
            EventBus.getDefault().post(callEvent);*/
        }

        @Override
        public void onUserVideoAvailable(String userId, boolean isVideoAvailable) {
            LogUtils.d("onUserVideoAvailable");
            LogUtils.e(userId);
            CallEvent callEvent = new CallEvent();
            callEvent.type = Common.onUserVideoAvailable;
            callEvent.isVideoAvailable = isVideoAvailable;
            callEvent.userId = userId;
            EventBus.getDefault().post(callEvent);
        }

        @Override
        public void onUserAudioAvailable(String userId, boolean isVideoAvailable) {
            LogUtils.d("onUserAudioAvailable");

        }

        @Override
        public void onUserVoiceVolume(Map<String, Integer> volumeMap) {
            LogUtils.d("onUserVoiceVolume");

        }
    };

    private V2TIMSimpleMsgListener v2TIMSimpleMsgListener = new V2TIMSimpleMsgListener() {
        @Override
        public void onRecvC2CTextMessage(String msgID, V2TIMUserInfo sender, String text) {
            LogUtils.e("接收IM：" + msgID + "-" + text);
            try {
                IMEventBean imEventBean = new Gson().fromJson(text, IMEventBean.class);
                CallEvent callEvent = new CallEvent();
                callEvent.type = imEventBean.type;
                callEvent.classId = imEventBean.classId;
                callEvent.orderId = imEventBean.orderId;
                EventBus.getDefault().post(callEvent);
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        @Override
        public void onRecvC2CCustomMessage(String msgID, V2TIMUserInfo sender, byte[] customData) {
            try {
                String s = new String(customData);
                LogUtils.e(s);
                IMEventBean imEventBean = new Gson().fromJson(s, IMEventBean.class);
                if(imEventBean.type == 0){
                    return;
                }
                CallEvent callEvent = new CallEvent();
                callEvent.type = imEventBean.type;
                callEvent.classId = imEventBean.classId;
                callEvent.orderId = imEventBean.orderId;
                EventBus.getDefault().post(callEvent);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    };

    public static void start(Context context) {
        if (ServiceUtils.isServiceRunning(CallService.class)) {
            return;
        }
        Intent starter = new Intent(context, CallService.class);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(starter);
        } else {
            context.startService(starter);
        }
    }

    public static void stop(Context context) {
        Intent intent = new Intent(context, CallService.class);
        context.stopService(intent);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        // 获取服务通知
        EventBus.getDefault().register(this);
        Notification notification = createForegroundNotification();
        //将服务置于启动状态 ,NOTIFICATION_ID指的是创建的通知的ID
        startForeground(NOTIFICATION_ID, notification);
        initWebSocket();

        // 由于两个模块公用一个IM，所以需要在这里先进行登录，您的App只使用一个model，可以直接调用VideoCall 对应函数
        // 目前 Demo 为了方便您接入，使用的是本地签发 sig 的方式，您的项目上线，务必要保证将签发逻辑转移到服务端，否者会出现 key 被盗用，流量盗用的风险。
        if (SessionWrapper.isMainProcess(this)) {
            V2TIMSDKConfig config = new V2TIMSDKConfig();
            config.setLogLevel(V2TIMSDKConfig.V2TIM_LOG_DEBUG);
            V2TIMManager.getInstance().initSDK(this, Common.SDKAPPID, config, new V2TIMSDKListener() {
                @Override
                public void onConnecting() {
                }

                @Override
                public void onConnectSuccess() {
                }

                @Override
                public void onConnectFailed(int code, String error) {
                }
            });
        }
        String userId = AppHelper.getInstance().getUser().getUserId();
        String userSig = GenerateTestUserSig.genTestUserSig(userId);
        Log.d("Login", "login: " + userId + " " + userSig);
        // 由于这里提前登陆了，所以会导致上一次的消息收不到，您在APP中单独使用 ITRTCAudioCall.login 不会出现这种问题
        V2TIMManager.getInstance().login(userId, userSig, new V2TIMCallback() {
            @Override
            public void onError(int i, String s) {
                // 登录IM失败
                LogUtils.e("IM登录失败：" + i + "-" + s);
                ToastUtil.show(CallService.this, "IM登录失败：" + i + "-" + s);
            }

            @Override
            public void onSuccess() {
                //1. 登录IM成功
                LogUtils.e("IM登录成功");
                initTxy();
                initTic();
            }
        });
        V2TIMManager.getInstance().addSimpleMsgListener(v2TIMSimpleMsgListener);
    }

    private void initWebSocket() {
        OkHttpClient client = new OkHttpClient.Builder()
                .retryOnConnectionFailure(true)//允许失败重试
                .readTimeout(5, TimeUnit.SECONDS)//设置读取超时时间
                .writeTimeout(5, TimeUnit.SECONDS)//设置写的超时时间
                .connectTimeout(5, TimeUnit.SECONDS)//设置连接超时时间
                .build();
        String url = TwjfApi.serviceUrl + "heaven-api/api/myWS?token=" + AppHelper.getInstance().getToken();
        LogUtils.d(url);
        Request request  = new Request.Builder().url(url).build();
        webSocket = client.newWebSocket(request, new WebSocketListener() {
            @Override
            public void onOpen(WebSocket webSocket, Response response) {
                super.onOpen(webSocket, response);
                LogUtils.d("onOpen");
            }

            @Override
            public void onMessage(WebSocket webSocket, String text) {
                super.onMessage(webSocket, text);
                LogUtils.d("onMessage:" + text);
                Message message = new Message();
                message.what = 10001;
                message.obj = text;
                uiHandler.sendMessage(message);
            }

            @Override
            public void onMessage(WebSocket webSocket, ByteString bytes) {
                super.onMessage(webSocket, bytes);
                LogUtils.d("onMessage");
            }

            @Override
            public void onClosing(WebSocket webSocket, int code, String reason) {
                super.onClosing(webSocket, code, reason);
                LogUtils.d("onClosing");
            }

            @Override
            public void onClosed(WebSocket webSocket, int code, String reason) {
                super.onClosed(webSocket, code, reason);
                LogUtils.d("onClosed");
            }

            @Override
            public void onFailure(WebSocket webSocket, Throwable t,  Response response) {
                super.onFailure(webSocket, t, response);
                LogUtils.e("onFailure");
                LogUtils.e(t);
                LogUtils.e(response);
            }
        });
    }

    private void initTxy() {
        mTRTCCalling = TRTCCallingImpl.sharedInstance(this);
        mTRTCCalling.addDelegate(delegate);
        String userId = AppHelper.getInstance().getUser().getUserId();
        String userSig = GenerateTestUserSig.genTestUserSig(userId);
        mTRTCCalling.login(Common.SDKAPPID, userId, userSig, new TRTCCalling.ActionCallBack() {
            @Override
            public void onError(int code, String msg) {
                LogUtils.e("腾讯云登录失败：" + code + "-" + msg);
                ToastUtil.show(CallService.this, "腾讯云登录失败：" + code + "-" + msg);
            }

            @Override
            public void onSuccess() {
                LogUtils.e("腾讯云登录成功");
            }
        });
    }

    private void initTic() {
        mTicManager = MainApplication.getTICManager();
        String userId = AppHelper.getInstance().getUser().getUserId();
        String userSig = GenerateTestUserSig.genTestUserSig(userId);
        mTicManager.login(userId, userSig, new TICManager.TICCallback() {
            @Override
            public void onSuccess(Object data) {
                LogUtils.e("Tic登录成功");
            }

            @Override
            public void onError(String module, int errCode, String errMsg) {
                LogUtils.e(":登录失败, err:" + errCode + "  msg: " + errMsg);
            }
        });
    }

    private Notification createForegroundNotification() {
        // 唯一的通知通道的id.
        String notificationChannelId = "tell_win_id_01";
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        // Android8.0以上的系统，新建消息通道
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            //用户可见的通道名称
            String channelName = "TRTC Foreground Service Notification";
            //通道的重要程度
            int importance = NotificationManager.IMPORTANCE_MIN;
            NotificationChannel notificationChannel = new NotificationChannel(notificationChannelId, channelName, importance);
            notificationChannel.setDescription("Channel description");
            notificationChannel.setSound(null, null);
            //震动
            //  notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
            notificationChannel.enableVibration(false);
            if (notificationManager != null) {
                notificationManager.createNotificationChannel(notificationChannel);
            }
        }

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, notificationChannelId);
        //不要震动和声音
        builder.setDefaults(NotificationCompat.FLAG_ONLY_ALERT_ONCE);//统一消除声音和震动
        builder.setVibrate(new long[]{0});
        builder.setSound(null);

        //通知小图标
        builder.setSmallIcon(R.mipmap.app_icon);
        //通知标题
        builder.setContentTitle(getString(R.string.app_name));
        //通知内容
        builder.setContentText("");
        //设定通知显示的时间
        builder.setWhen(System.currentTimeMillis());

        //创建通知并返回
        return builder.build();
    }

    @Subscribe
    public void onEvent(WebSocketEvent event) {
        if(webSocket!=null){
            webSocket.close(1002 , "切换身份");
            webSocket = null;
        }
        initWebSocket();
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        LogUtils.i("onDestory");
        if (mTRTCCalling != null) {
            mTRTCCalling.removeDelegate(delegate);
            mTRTCCalling.logout(null);
            V2TIMManager.getInstance().logout(null);
            V2TIMManager.getInstance().unInitSDK();
        }
        if(webSocket!=null){
            webSocket.close(1001 , "关闭连接");
            webSocket = null;
        }

        EventBus.getDefault().unregister(this);
    }


    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
}
